#import "wooddoc.h"
#import "ScrollViewDeluxeForOOE.h"
#import "Ruler.h"

@implementation WoodDoc (Creation)

static const int 	classVersion		= 100;		// version number * 100
static NXCoord 		origX 				= 300.0;	// doc starting position
static NXCoord 		origY 				= 200.0;
static NXCoord		posInc 				= 20.0;		// increment to position
static BOOL			shouldIncPos		= YES;
static int          tagProvider 		= 0; 

+ initialize
{
    if(self == [WoodDoc class]){
		[self setVersion:classVersion];
		[self setDocExtension:localString("wood")];
		[self setDefaultTitleFormat:localString("Untitled%d")];
		[self initializePasteboardTypes];
	}
	return self;
}

+ setIncPos:(BOOL)aBool
{
	shouldIncPos = aBool;
	return self;
}

- initFromFile:(const char *)file
{
    NXTypedStream *stream;
    char *strPtr = rindex(file, '.');
	BOOL shouldRegister = NO;
	
	if(strcmp([[self class] docExtension],++strPtr)) 
		return [self initFromPasteboard:[Pasteboard newByFilteringFile:file]];
    stream = NXOpenTypedStreamForFile(file,NX_READONLY);
    if(stream){
    	if([self setUpNib]){	
			[window setTitle:localString("Loading...")];		
			if([self loadTreeFrom:stream]){
				[self instanceAwake];
				[self dirty:NO];
				[self updateViewsDirty:NO rect:NULL flag:(UPDATE_ALL | SCROLL_TREEVIEW)];
				[self setSavedDocument:YES];
				[self setEmpty:(tree ? NO : YES)];
				[self setName:file];
				[window makeKeyAndOrderFront:self];
				shouldRegister = YES;
			}
		} else 
			Notify(localString("WoodDoc: can't set up doc nib"),file);
		NXCloseTypedStream(stream);
		if(shouldRegister){
			[NXApp registerDoc:self];
			return self;
		} else {
			[self free];
			return nil;
		}
    } else {
		Notify(localString("WoodDoc: can't open file"),file);
		[self free];
		return nil;
    }
}

- initOOEFromFile:(const char *)file
{
    NXTypedStream *stream;
    char *strPtr = rindex(file, '.');
	BOOL shouldRegister = NO;
	
	if(strcmp([[self class] docExtension],++strPtr)) 
		return [self initFromPasteboard:[Pasteboard newByFilteringFile:file]];
    stream = NXOpenTypedStreamForFile(file,NX_READONLY);
    if(stream){
    	if([self setUpNib]){	
			[window setTitle:localString("Loading...")];		
			if([self loadTreeFrom:stream]){
				[self instanceAwake];
				[self dirty:NO];
				[self updateViewsDirty:NO rect:NULL flag:(UPDATE_ALL | SCROLL_TREEVIEW)];
				[self setSavedDocument:YES];
				[self setEmpty:(tree ? NO : YES)];
				[self setName:file];
				shouldRegister = YES;
			}
		} else 
			Notify(localString("WoodDoc: can't set up doc nib"),file);
		NXCloseTypedStream(stream);
		if(shouldRegister){
			[NXApp registerDoc:self];
			return self;
		} else {
			[self free];
			return nil;
		}
    } else {
		Notify(localString("WoodDoc: can't open file"),file);
		[self free];
		return nil;
    }
}

- initFromPasteboard:pasteboard
{
	char *stringPos, *tempPtr, *pathList;
	char tempBuf[MAXPATHLEN+1];
	char **filePath = NULL;
	int files = 0, length = 0, count = 0;
	BOOL flag = NO;
	id pBoard = [Pasteboard newByFilteringTypesInPasteboard:pasteboard];
    
	if ([pBoard findAvailableTypeFrom:&NXFilenamePboardType num:1]) {
		if ([pBoard readType:NXFilenamePboardType data:&pathList length:&length]) 
			flag = YES;
	} else if ([pBoard findAvailableTypeFrom:&NXAsciiPboardType num:1]) {
		if ([pBoard readType:NXAsciiPboardType data:&pathList length:&length]) 
			flag = YES;
	}
	if (!flag) {
		Notify(localString("Pasteboard"),
			   localString("Could not parse or filter ASCII data from the requested source."));
		return nil;
	}
	stringPos = tempPtr = pathList;
	while (stringPos = index(stringPos, '\t')) {
		count = (int)(stringPos-tempPtr);
		strncpy(tempBuf,tempPtr,count);
		*(tempBuf+count) = '\0';
		filePath = addFile(tempBuf,filePath,files,[self zone]);
		files++;
		stringPos++;
		tempPtr=stringPos;
    }
	count = strlen(tempPtr);
	strncpy(tempBuf,tempPtr,count);
	*(tempBuf+count) = '\0';
	filePath = addFile(tempBuf,filePath,files,[self zone]);
	files++;
	while (files--) {
		if (![[[NXApp docClass] allocFromZone:[NXApp newDocZone]] initFromFile:filePath[files]]) 
			Notify(localString("Pasteboard: can't open file"),filePath[files]);
	}
	freeList(filePath);
	[pBoard deallocatePasteboardData:pathList length:length];
	return self;
}

- initNewOOE:client
{
	[self init];
	[self connectToClient:client];
	[self setTitle_OOE:nil];
	return self;
}

- initOOE:client
{
	[self initNewOOE:client];
	[self retrieveData:client];
	return self;
}

- init
{
	if([self setUpNib]){
		tree = nil;
		printInfo = [DGPrintInfo new];
    	[printInfo setMarginLeft:36.0 right:36.0 top:36.0 bottom:36.0];
		[printInfo setHorizCentered:YES];
   		[printInfo setVertCentered:YES];
		[self instanceAwake];
		[self dirty:NO];
    	[self setSavedDocument:NO];
		[self setEmpty:YES];
    	[self setName:NULL andDirectory:NULL];
		[NXApp registerDoc:self];
		[window makeKeyAndOrderFront:self];
		return self;
	} else
		return nil;
}

- setUpNib
{
    [NXApp loadLocalNib:"WoodDoc" owner:self];
	return self;
}

- instanceAwake
{
	NXRect frameRect;
	
	tag = tagProvider++;
	undoManager = [[UndoManager allocFromZone:[self zone]] init];
	[undoManager addUndoDelegate:self];
	lastSelectedNode = nil;
	findSelectedNode = nil;
	isOOEServer = NO;
	theOOEClient = nil;
	theOOEClientPath = NULL;
	docScale = 1.0;
	showMarker = YES;
	defaultProps.border = 10.0;
	defaultProps.parentDistance = 30.0;
	defaultProps.zipped = NO;
	defaultProps.shadow = YES;
	defaultProps.fill = YES;
	defaultProps.outline = YES;
	defaultProps.font = [Font newFont:"Times-Roman" size:12.0];
	defaultProps.pathKind = RECT_NODETYPE;
	defaultProps.linkKind = 1;
	defaultProps.biegFactor = 0.33;
	defaultProps.fillColor = NX_COLORWHITE;
	defaultProps.outlineColor = NX_COLORBLACK;
	defaultProps.textColor = NX_COLORBLACK;
	defaultProps.shadowColor = NX_COLORLTGRAY;
	defaultProps.defaultNodeName = NXCopyStringBuffer("Node");
	defaultProps.ending = ENDING_NONE;
	defaultProps.parentEnding = ENDING_NONE;
	[window moveTo:origX :origY];
	if(shouldIncPos){
		origX += posInc; origY -= posInc;
		if(origX > 700) 
			origX = 110;
		if(origY < 0) 
			origY = 70;
	}
    [window setDelegate:self];
	calcFrame(printInfo,&frameRect);
    treeView = [[TreeView allocFromZone:[window zone]] initFrame:&frameRect];
	[treeView setAgent:self];
    NXSetRect(&frameRect,0,0,100,100);
    scrollView = [[ScrollViewDeluxeForOOE allocFromZone:[window zone]] initFrame:&frameRect];
	[scrollView setDocView:treeView];
	[scrollView setZoomButtonVisible:YES];
	[scrollView setRulerClass:[Ruler class]];
	[scrollView hideRulers:self];
	[scrollView setPageLeftRightButtonsVisible:NO];
	[scrollView setPageUpDownButtonsVisible:NO];
	[textView removeFromSuperview];
	[[textView docView] setDelegate:self];   	
   	[doubleView addSubview:scrollView];
    [doubleView addSubview:textView];
    [doubleView display];
	[window makeFirstResponder:treeView];
	textViewSaved = YES;
	saveToAccessoryWindow = nil;
	saveToAccessoryControl = nil;
	return self;
}

- loadTreeFrom:(NXTypedStream *)stream
{
	id ret = self;
	NX_DURING
		tree = NXReadObject(stream);
		[tree setDelegateRecursive:self];
		printInfo = NXReadObject(stream);
	NX_HANDLER
		switch(NXLocalHandler.code){
			case TYPEDSTREAM_CALLER_ERROR: 
					NXRunAlertPanel(0,"Typed stream caller error",0,0,0);
					ret = nil;
					break;
			case TYPEDSTREAM_FILE_INCONSISTENCY:
					NXRunAlertPanel(0,"Typed stream file inconsistency",0,0,0);
					ret = nil;
					break;
			case TYPEDSTREAM_CLASS_ERROR:
					NXRunAlertPanel(0,"Typed stream class error",0,0,0);
					ret = nil;
					break;
			case TYPEDSTREAM_TYPE_DESCRIPTOR_ERROR:
					NXRunAlertPanel(0,"Typed stream descriptor error",0,0,0);
					ret = nil;
					break;
			case TYPEDSTREAM_WRITE_REFERENCE_ERROR:
					NXRunAlertPanel(0,"Typed stream write reference error",0,0,0);
					ret = nil;
					break;
			case TYPEDSTREAM_INTERNAL_ERROR:
					NXRunAlertPanel(0,"Typed stream internal error",0,0,0);
					ret = nil;
					break;
		}
	NX_ENDHANDLER
	return ret;
}

@end

